1. /* sifiisub.cpp by K.Tsuru */
  2. // function ID = 422 BRADIX
  3. // bugfix in version 2.16
  4. /******************************************
  5. SInteger class
  6. It provides the subtraction result = m - n.
  7. ******************************************/
  8. #ifndef SN_H
  9. #include "sn.h"
  10. #endif
  11. void IISub(const SInteger& m, const SInteger& n, SInteger& result){
  12. int sgn = m.Sign(422) * n.Sign(422), c;
  13. if(!sgn){
  14. if(!m.Sign()){ // m = 0
  15. result = n; result.ChangeSign(); // result = 0 - n;
  16. } else result = m; // result = m - 0;
  17. return;
  18. } else if(sgn < 0){ //different sign m - n = m + (-n)
  19. // Notice the case "&result == &m" or "&result == &n".
  20. SInteger temp(n); // bugfix ver. 2.16 on Jul 31, 2002
  21. temp.ChangeSign(); // temp = -n
  22. IIAdd(m, temp, result); //The sign is the same as that of m and set in IIAdd().
  23. return;
  24. }
  25. // Here m and n have the same sign.
  26. c = LLCompare(m, n);
  27. sgn = m.Sign();
  28. if(c < 0){ // |n| > |m|, m-n = -(n-m)
  29. IISub(n, m, result); result.ChangeSign(); return;
  30. } else if(!c){ //same value m == n
  31. result.SetZero(); return;
  32. }
  33. // Here |m| > |n| ("c > 0 && mh >= nh") and evaluate m - n.
  34. // m and n have the same sign and the figures of m is greater than or equal to that of n.
  35. if(n.aHead == 0){ // n has one figure.
  36. // bugfix ver. 2.16
  37. if(n.Sign() > 0) IsSub(m, n(0), result); // 0 < n < m, m - n = m - n(0)
  38. else IsAdd(m, n(0), result); // m < n < 0, m - n = m + n(0)
  39. result.SetSign(sgn);
  40. return;
  41. }
  42. uint mh = m.Head(), nh = n.Head();
  43. uint rt = min( m.Tail(), n.Tail() );
  44. #ifndef NDEBUG
  45. assert(mh >= nh);
  46. #endif
  47. /*
  48. Neither IISub(L, z, L); nor IISub(z, L, L);
  49. it allocates the memory of "result" and initializes it.
  50. */
  51. if( (&m != &result) && (&n != &result) ){
  52. result.valloc(m.Size(), -1);
  53. if(rt) result.figure.clear(0, rt -1u);
  54. result.figure.clear(mh+1u);
  55. } else result.Reserve(mh); // IISub(z, L, L); z > L(=result)
  56. const fType* mv = m.ReadFigures();
  57. const fType* nv = n.ReadFigures();
  58. fType* rv = result.figure.Elements();
  59. #ifndef NDEBUG
  60. result.figure(mh);
  61. #endif
  62. // mh >= nh
  63. uint i;
  64. fType u = 0; //borrow from upper figure, 0 or 1
  65. for(i = rt; i <= nh; i++) {
  66. u = mv[i] - nv[i] - u;
  67. rv[i] = u & BRADIX1;
  68. //u = (u & BRADIX) ? 1 : 0;
  69. u = u >> BRADIX_BITS; // 0 or 1
  70. }
  71. //processing upper figures
  72. for( ; u && (i <= mh) ; i++) {
  73. //The borrow is non-zero.
  74. u = mv[i] - u;
  75. rv[i] = u & BRADIX1;
  76. //u = (u & BRADIX) ? 1 : 0;
  77. u = u >> BRADIX_BITS;
  78. }
  79. #ifndef NDEBUG
  80. assert(u == 0);
  81. #endif
  82. if((mh >= i) && (rv != mv) ){ //no borrw (u = 0)
  83. memcpy(rv + i, mv + i, sizeof(fType)*(mh-i+1u));
  84. // while(i <= mh){ rv[i] = mv[i]; i++; }
  85. }
  86. //It gets the figure positions.
  87. while( !rv[rt] ) rt++;
  88. while( !rv[mh] ) mh--;
  89. result.aHead = mh;
  90. result.aTail = rt;
  91. result.SetSign(sgn);
  92. //If the figures decrease it reduces the size.
  93. if( 2u*(result.aHead+1) <= result.figure.size() ) result.DoCutDown();
  94. }

sifiisub.cpp : last modifiled at 2017/03/13 14:31:59(2,989 bytes)
created at 2016/04/25 14:53:17
The creation time of this html file is 2017/10/25 11:09:45 (Wed Oct 25 11:09:45 2017).